//
//  SWBleManager.m
//  EKLLighting
//
//  Created by Chris on 2021/4/30.
//

#import "SWBleManager.h"


static SWBleManager * sharedSingleton = nil;

@interface SWBleManager()

@property(nonatomic, strong) dispatch_queue_t eklCommandQueue;
@property(nonatomic, strong) NSMutableDictionary *bleModelDictionary;
@property(nonatomic, strong) NSTimer *heartTimer;
@end

@implementation SWBleManager


+ (SWBleManager *)sharedManager {
    if (sharedSingleton == nil) {
        @synchronized (self) {
            if (sharedSingleton == nil) {
                sharedSingleton = [[SWBleManager alloc] init];
//                sharedSingleton.bleState = CBManagerStatePoweredOn;
            }
        }
    }
//    static dispatch_once_t once;
//    dispatch_once(&once, ^{
//        instance = [[SWBleManager alloc] init];
//    });
    return sharedSingleton;
}

- (void)BleDealloc{
    sharedSingleton = nil;
}

- (instancetype)init{
    self = [super init];
    if (self){
        self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:nil];
        self.eklCommandQueue = dispatch_get_main_queue();
        self.bleModelDictionary = [NSMutableDictionary dictionary];
        _reConnectDeviceArray = [NSMutableArray array];
    }
    return self;
}

- (NSString *)uuid {
    if (self.currentPeri) {
        return self.currentPeri.identifier.UUIDString;
    }
    NSString * u = [[NSUserDefaults standardUserDefaults] valueForKey:@"lastconnectuuid"];
    if (u.length) {
        return u;
    }
    return @"";
}

/*
 * 扫描
 * scan
 */
- (void)scanPeriperals:(_Nullable DiscoverPeriperalsBlock)discoverPeriperals{
    _discoverPeriBlock = discoverPeriperals;
    CBUUID  *serviceUUID    = [CBUUID UUIDWithString: CharacteristicServiceUUIDWrite];
    [self.centralManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@(NO)}];
    
    //已经被系统或者其他APP连接上的设备数组
               NSArray *arr = [self.centralManager retrieveConnectedPeripheralsWithServices:@[serviceUUID]];//serviceUUID就是你首次连接配对的蓝牙
               NSLog(@"%@",arr);
               if(arr.count>0)
               {
                   for (CBPeripheral* peripheral in arr)
                   {
                       if (peripheral != nil)
                       {
                           if (_discoverPeriBlock) {
                               _discoverPeriBlock(self.centralManager, peripheral, nil, nil);
                           }
//                           self.currentPeri = peripheral;//这一个必须要，需要一个全局变量接受，否则无法连接
//                           self.currentPeri.delegate  = self;
//                           [self.centralManager connectPeripheral:self.currentPeri options:nil];
                       }
                   }
               }
}

/*
 * 停止扫描
 * stop scan
 */
- (void)stopScanPeriperals{
    [self.centralManager stopScan];
}

/*
 * 连接
 * connect
 */
- (void)connectToPeripheral:(CBPeripheral *)peripheral success:(SuccessConnectToPeriperalBlock)success fail:(FailConnectToPeriperalBlock)fail characteristic:(DiscoverCharacteristicBlock)characteristic
{
    _successBlock = success;
    _failBlock = fail;
    _discoverCharacteristicBlock = characteristic;
    if (peripheral) {
        [self.centralManager connectPeripheral:peripheral options:nil];
        NSLog(@"开始链接设备");
    }
}

/*
 * 断开连接
 * cancel connect
 */
- (void)cancelConnectToPeripheral:(_Nullable CancelConnectToPeriperalBlock)cancel
{
    _cancelBlock = cancel;
    [self destroyBleConnect];
    _weakself;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if (weakself.cancelBlock) {
            weakself.cancelBlock(nil, nil, nil);
            weakself.cancelBlock = nil;
        }
    });
}

- (void)destroyBleConnect
{
    _discoverCharacteristicBlock = nil;
    _writeCharacter = nil;
    [_bleModelDictionary removeAllObjects];
    if (_currentPeri) {
        [self.centralManager cancelPeripheralConnection:_currentPeri];
    }
    [self BleDealloc];
}

- (void)removeAllCommand
{
    [_bleModelDictionary removeAllObjects];
}

/*
 * 发送数据
 * send data
 */

+ (void)sendDataToPeri:(Byte *)cmd completion:(void (^ _Nullable)(HABleModel *bleModel))completion
{
    [SWBleManager sendDataToPeri:cmd lenght:CMD_LENGHT completion:completion];
}

+ (void)sendDataToPeri:(Byte *)cmd lenght:(NSInteger)lenght completion:(void (^ _Nullable)(HABleModel *bleModel))completion {
    
    NSData *command = [NSData dataWithBytes:cmd length:lenght];
//    [[SWBleManager sharedManager] sendCommandData:command completion:completion];
}

- (void)sendCommandData:(NSData *)command completion:(void (^)(NSString * _Nonnull))completion
{
    NSString *cmdHexString = [HABleTool convertDataToHexStr:command];
    
//    SWBleManager *eleMgr = [SWBleManager sharedManager];
    
//    HABleModel *bleModel = [[HABleModel alloc] init];
//    bleModel.bleCompleHander = completion;
    self.resultBlock = completion;
    if (!self.writeCharacter) {
        return;
    }
    
    if (self.currentPeri && self.writeCharacter) {
//        if (!self.writeCharacter.isNotifying) {
//            [self.currentPeri setNotifyValue:YES forCharacteristic:self.writeCharacter];
//        }
//        self.bleModelDictionary[[cmdHeader stringByAppendingString:@"ble"]] = bleModel;  //蓝牙，wifi的逻辑我去掉了

        dispatch_block_t commandTask = ^{
            [self.currentPeri writeValue:command
                 forCharacteristic:self.writeCharacter
                             type:CBCharacteristicWriteWithoutResponse];
            NSLog(@"数据发送.%ld",command.length);
        };
        dispatch_async(self.eklCommandQueue, commandTask);
    }
}

/*
 * 读取信号量
 * read RSSI
 */
- (void)readRSSIWithPeriperal:(CBPeripheral *)peripheral{
    [peripheral readRSSI];
}



- (void)handleRecvData:(NSData *)data topic:(NSString *)topic
{
    if (data.length) {
        Byte * testByte = (Byte*)[data bytes];
        for(int i=0;i<[data length];i++)
        {
            NSLog(@"recvie ==== %d\n",testByte[i]);
        }
    }
    
    NSString *dataString = [HABleTool convertDataToHexStr:data];
    NSLog(@"recvie ==== %@",dataString);
    return;
   
}



- (BOOL)bleAvaliable
{
    BOOL avaliable = [_isAvaliable boolValue];
    return avaliable;
}

- (NSTimer *)heartTimer{
    if (!_heartTimer){
        _weakself;
//        NSString * str = @"Gvbr7pKTc1E8UiYPcPgyJaqbOOqc72ewe8sdMY/8+aRiQp6wVrUhkjGrfduYjz+qgGx50UtjMu+S2EttP+nbiGEnlPgJu2DV7jD0n6ZFPlpvR/+2yhwiuFmYNgmRweyNV42sXKIiF16bL8tU6pUkk1a9OmfQXsweVPDs+z0kQK4=";   72
//        [JcProgressHUD showMessage:@"数据发送中..."];
        NSLog(@"%ld",self.dataStr.length);
        NSMutableArray * arr = [[NSMutableArray alloc] init];
        int begin = 20;
        
        int shang = self.dataStr.length / 20;
        int yushu = self.dataStr.length % 20;
        
        for (int i = 0; i < shang + 1; i++) {
            if (i < shang) {
                NSString * substr = [self.dataStr substringWithRange:NSMakeRange(i * begin, 20)];
                NSData * data = [substr dataUsingEncoding:NSUTF8StringEncoding];
                [arr addObject:data];
            }else{
                NSString * substr = [self.dataStr substringWithRange:NSMakeRange(i * begin, yushu)];
                NSData * data = [substr dataUsingEncoding:NSUTF8StringEncoding];
                [arr addObject:data];
            }
        }
        __block int times = 0;
        _heartTimer = [NSTimer scheduledTimerWithTimeInterval:0.4 block:^(NSTimer * _Nonnull timer) {
            
             if (weakself.currentPeri && weakself.writeCharacter) {
//                 [self sendCommandData:arr[times] completion:^(HABleModel * _Nonnull bleModel) {
//                     NSLog(@"heartTimer: %@", bleModel.cmdHeader);
//                 }];
                 [self sendCommandData:arr[times] completion:^(NSString * _Nonnull resultString) {
                                      
                 }];
                 times++;
                 if (times > shang) {
                     [[SWBleManager sharedManager] stopHeartBeat];
 //                    [JcProgressHUD showMessage:@"数据发送完成,请等待"];
                 }

             }else {
                 if ([self bleAvaliable]) {
                     CBUUID  *serviceUUID    = [CBUUID UUIDWithString:CharacteristicServiceUUIDWrite];
                     [self.centralManager scanForPeripheralsWithServices:@[serviceUUID] options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@(NO)}];                }
             }
        } repeats:YES];

        
//        // 将定时器加入循环。mode为NSRunLoopCommonModes，防止页面滑动造成定时器停止。
//        [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
    }
    return _heartTimer;
}

- (void)startHeartBeat
{
    NSTimer *timer = [self heartTimer];
    [timer fire];
}

- (BOOL)isHeartTimerValid
{
    return [_heartTimer isValid];
}

- (void)stopHeartBeat
{
    [_heartTimer invalidate];
    _heartTimer = nil;
}

#pragma mark - CBCentralManagerDelegate
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
    _isAvaliable = @"0";
    self.bleState = central.state;
    switch (central.state){
        case CBManagerStatePoweredOn:
            NSLog(@"蓝牙开启且可用");
            _isAvaliable = @"1";
            [self scanPeriperals:_discoverPeriBlock];
            break;
        case CBManagerStateUnknown:
//            [JcProgressHUD showMessage:@"手机没有识别到蓝牙，请检查手机。"];
            break;
        case CBManagerStateResetting:
//            [JcProgressHUD showMessage:@"手机蓝牙已断开连接，重置中。"];
            break;
        case CBManagerStateUnsupported:
//            [JcProgressHUD showMessage:@"手机不支持蓝牙功能，请更换手机。"];
            break;
        case CBManagerStatePoweredOff:
//            [JcProgressHUD showMessage:@"手机蓝牙功能关闭，请打开蓝牙。"];
//        {
//            UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"手机蓝牙功能关闭，请打开蓝牙。" preferredStyle:UIAlertControllerStyleAlert];
//
//            UIAlertAction * action = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
//
//            }];
//
//            [alert addAction:action];
//
//            CDVAppDelegate * delegate = (CDVAppDelegate *)[UIApplication sharedApplication].delegate;
//            [delegate.window.rootViewController presentViewController:alert animated:YES completion:nil];
//        }
            break;
        case CBManagerStateUnauthorized:
//            [JcProgressHUD showMessage:@"请前往设置-隐私-蓝牙-鲁e行打开蓝牙功能。"];
//        {
//            UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"请前往设置-隐私-蓝牙-鲁e行打开蓝牙功能。" preferredStyle:UIAlertControllerStyleAlert];
//            
//            UIAlertAction * action = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
//                NSURL *url = [NSURL   URLWithString:UIApplicationOpenSettingsURLString];
//               [[UIApplication sharedApplication]openURL:url];
//            }];
//            
//            [alert addAction:action];
//            
//            CDVAppDelegate * delegate = (CDVAppDelegate *)[UIApplication sharedApplication].delegate;
//            [delegate.window.rootViewController presentViewController:alert animated:YES completion:nil];
//        }
            break;
    }
    if ([_isAvaliable isEqualToString:@"0"]) {
        _currentPeri = nil;
    }
   
}

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *, id> *)advertisementData RSSI:(NSNumber *)RSSI{
    NSData * data = advertisementData[@"kCBAdvDataManufacturerData"];
    NSString * string =  [self convertDataToHexStrBLE:data];
    NSLog(@"%@", [NSString stringWithFormat:@"发现一个设备 - %@" ,peripheral.name] );
    if (string.length > 16 && [[string substringWithRange:NSMakeRange(4, 4)] isEqualToString:@"5459"]) {
      
        peripheral.advertisementData = advertisementData;
        peripheral.macAddress = [string substringFromIndex:16];
        [[NSUserDefaults standardUserDefaults] setValue:peripheral.macAddress forKey:@"lastconnectmacaddress"];

        if (_discoverPeriBlock) {
            _discoverPeriBlock(central, peripheral, advertisementData, RSSI);
        }
    }
    
}

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
    _currentPeri = peripheral;
    _uuid = peripheral.identifier.UUIDString;
    [[NSUserDefaults standardUserDefaults] setValue:_uuid forKey:@"lastconnectuuid"];
    _centralManager = central;
//    NSString *bleName = [peripheral.advertisementData objectForKey:@"kCBAdvDataLocalName"];
//    NSLog(@"cmdHeader didConnectPeripheral: %@, %@", bleName, _currentPeri);
    if (_discoverCharacteristicBlock == nil) {
        [self destroyBleConnect];
        return;
    }
      
    peripheral.delegate = self;
    [self.centralManager stopScan];
    CBUUID  *serviceUUID    = [CBUUID UUIDWithString:CharacteristicServiceUUIDWrite];
    NSArray  *serviceArray  = [NSArray arrayWithObjects:serviceUUID, nil];
    [peripheral discoverServices:serviceArray];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:@"knotification_connectsuccess" object:nil];
}

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{
    _currentPeri = nil;
    [_reConnectDeviceArray removeAllObjects];
    if (_failBlock) {
        _failBlock(central, peripheral, error);
    }
}

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{
    _currentPeri = nil;
    [_reConnectDeviceArray removeAllObjects];
    if (_cancelBlock) {
        _cancelBlock(central, peripheral, error);
        _cancelBlock = nil;
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:@"CancelConnectToPeriperal" object:peripheral];
}

#pragma mark - CBPeripheralDelegate

- (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(NSError *)error{
   
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
    if (_discoverCharacteristicBlock == nil) {
        [self destroyBleConnect];
        return;
    }
    for (CBService *service in peripheral.services) {
        [peripheral discoverCharacteristics:nil forService:service];
        NSLog(@"发现service:%@",service.UUID.UUIDString);
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
    if (_discoverCharacteristicBlock == nil) {
        [self destroyBleConnect];
        return;
    }
    for (CBCharacteristic *cha in service.characteristics){
        NSLog(@"发现characteristics:%@",cha.UUID.UUIDString);

        if ([cha.UUID.UUIDString isEqualToString:CharacteristicUUIDWrite_SJ]){
            //获取特征
            _writeCharacter = cha;
            [peripheral setNotifyValue:YES forCharacteristic:cha];
            if (_discoverCharacteristicBlock) {
                _discoverCharacteristicBlock(peripheral, service, error);
            }
        }else if ([cha.UUID.UUIDString isEqualToString:CharacteristicUUIDNotify_SJ]){
            _notifyCharacter = cha;
            [peripheral setNotifyValue:YES forCharacteristic:cha];
        }
    }
   
    if (_writeCharacter && _notifyCharacter) {
        if (_successBlock) {
            _successBlock(self.centralManager, self.currentPeri);
        }
    }
   
}

//读蓝牙数据
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    if ([characteristic.UUID.UUIDString isEqualToString:CharacteristicUUIDNotify_SJ]){
        NSData *data = characteristic.value;
        NSString * result = [[HABleTool convertDataToArray:data] componentsJoinedByString:@""];
        if (self.resultBlock) {
            self.resultBlock(result);
        }
    }
    if ([characteristic.UUID.UUIDString isEqualToString:CharacteristicUUIDWrite_SJ]){
        NSData *data = characteristic.value;
        NSString * result = [[HABleTool convertDataToArray:data] componentsJoinedByString:@""];
        if (self.resultBlock) {
            self.resultBlock(result);
        }
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {
    NSData *data = characteristic.value;
    [self handleRecvData:data topic:nil];

}

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error
{
    if (_haWriteBlock) {
        _haWriteBlock(characteristic, error);
    }
}

-(NSString*)convertDataToHexStrBLE:(NSData*)data {
    if(!data || [data length] ==0)
    {
        return nil;
    }
    NSMutableString*string = [[NSMutableString alloc]initWithCapacity:[data length]];
    
    [data enumerateByteRangesUsingBlock:^(const void*bytes,NSRange byteRange,BOOL*stop) {
        
        unsigned char*dataBytes = (unsigned char*)bytes;
        
        for(NSInteger i =0; i < byteRange.length; i++)
            
        {
            
            NSString * hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) &0xff];
            
            if([hexStr length] ==2) {
                [string appendString:hexStr];
            }else
            {
                [string appendFormat:@"0%@", hexStr];
            }
        }
    }];
    return string;
}




@end
